#pragma once

#include <iostream>
#include <map>
#include "inifile.hpp"

using namespace std;
using namespace inifile;

struct conf_val
{
	conf_val(string s,string n)
		:section(s)
		,name(n)
	{

	}

	string name;
	string section;
	string data;
};

class conf {
public:
	conf & operator=(const conf &) = delete;
	conf(const conf &) = delete;
	static conf* instance();

	bool init(string config_path);

	void write(const string& section, const string& key, const string& value);

	template<typename T>
	static inline T get_conf(string key)
	{
		auto res = conf::instance()->conf_map_.find(key);
		if (res == conf::instance()->conf_map_.end()) throw std::logic_error("empty value");
		auto val = res->second;
		if constexpr (std::is_same_v<T, int32_t> || std::is_same_v<T, uint32_t> ||
			 std::is_same_v<T, char> || std::is_same_v<T, short>) {
			int r = std::atoi(val.data.c_str());
			/*if (val[0] != '0' && r == 0) {
				throw std::invalid_argument(std::string(val) + ": is not an integer");
			}*/
			return r;
		}
		else if constexpr (std::is_same_v<T, bool>) {

			if (val.data == "true") {
				return true;
			}
			else { 
				return false; 
			}
		}
		else
		{
			return val.data;
		}
	}
	

private:
	conf();
	vector<conf_val> conf_vec_;
	map<string, conf_val>conf_map_;
	inifile::IniFile ini;

	bool initalize_ = false;


};


